package ginv

import (
	"context"
	"gitee.com/filters/utils/errv"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"net/http"
	"reflect"
)

// WrapHandler ...
func WrapHandler(h interface{}) gin.HandlerFunc {
	if h == nil {
		panic("WrapHandler不能传入空")
	}
	t := reflect.TypeOf(h)
	if t.NumIn() < 3 {
		panic("入参必须填三个参数")
	}
	if reflect.TypeOf(h).Kind() != reflect.Func {
		panic("入参必须为函数")
	}
	if typeContext.AssignableTo(t.In(0)) && t.Out(0).AssignableTo(typeError) {
		return wrapType31(reflect.ValueOf(h))
	}
	panic("未找到此函数")
}

func wrapType31(hv reflect.Value) gin.HandlerFunc {
	t := hv.Type()
	return func(c *gin.Context) {
		var reqValue []reflect.Value
		var rspV reflect.Value
		defaultContext = c
		ctx = context.WithValue(c, RequestId, uuid.New().String())
		ctx, cancel := context.WithTimeout(ctx, DefaultGinTime)
		defer cancel()
		//GinSet(c, RequestId, uuid.New().String())
		reqValue = append(reqValue, reflect.ValueOf(ctx))
		for i := 1; i < t.NumIn(); i++ {
			reqV, _ := inparam(c, t.In(i).Elem())
			reqValue = append(reqValue, reqV)
			if i == 2 {
				rspV = reqV
			}
		}
		out := hv.Call(reqValue)
		es, _ := out[0].Interface().(error)
		DefaultRspRenderer(c, rspV.Interface(), es)
	}
}

// DefaultRspRenderer 默认的请求结果处理函数
func DefaultRspRenderer(c *gin.Context, rsp interface{}, err error) {
	if err != nil {
		if codedErr, ok := err.(*errv.ErrWrap); ok {
			c.JSON(http.StatusOK, codedErr)
			return
		}
		c.JSON(http.StatusOK, c.Error(err))
		return
	}
	c.JSON(http.StatusOK, rsp)
	return
}
